package org.apache.directory.mavibot.btree;

import java.io.File;
import java.io.FileWriter;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import javax.management.JMX;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

import org.apache.directory.mavibot.btree.serializer.LongSerializer;

public class BenchMarchInsertValue {
	public static void main( String[] args ) throws Exception
	{
		if( args.length!=5 )
		{
			System.out.println( "wrong number of arguments" );
			return;
		}

		List<Tuple<Long, Long>> sortedTuple = new ArrayList<Tuple<Long, Long>>();
		File file = File.createTempFile( "managedbtreebuilder", ".data" );
	    file.deleteOnExit();

	    RecordManager rm = new RecordManager( file.getAbsolutePath() );

	    LongSerializer ser = new LongSerializer();
	    PersistedBTreeBuilder<Long, Long> bb = new PersistedBTreeBuilder<Long, Long>( rm, "master", 4, ser,
	        ser );
	    
	    MBeanServerConnection mBeanServerConnection = ManagementFactory.getPlatformMBeanServer();
	    ObjectName objThread = mBeanServerConnection.queryNames(new ObjectName("java.lang:type=Memory"), null).iterator().next();
	    MemoryMXBean memoryMXBean = JMX.newMXBeanProxy(mBeanServerConnection, objThread, java.lang.management.MemoryMXBean.class,false);
	    MemoryUsage mhu= memoryMXBean.getHeapMemoryUsage();
	    
		int cacheSize=Integer.parseInt(args[1]);
		int nbThread = Integer.parseInt(args[2]);
		Long duration = Long.parseLong(args[3]);
		PersistedBTree<Long, Long> btree = ( PersistedBTree<Long, Long> ) bb.build( sortedTuple.iterator() );
		final CountDownLatch latch = new CountDownLatch( nbThread );
		ArrayList<MyThreadTest> tabThreads = new ArrayList<MyThreadTest>();
		MyThreadTest mythreadTemp;
		for(long i=0;i<cacheSize;i++)
		{
			btree.insert(i, i);
		}
		long nbBytesBegin=mhu.getUsed();
		for ( int i = 0; i < nbThread; i++ )
		{
			mythreadTemp = new MyThreadTest( latch, i, btree, duration,
					cacheSize );
			tabThreads.add( mythreadTemp );
			mythreadTemp.start();
		}
		latch.await();
		mhu= memoryMXBean.getHeapMemoryUsage();
		long nbBytesEnd=mhu.getUsed();
		FileWriter myFileWriter=new FileWriter(args[4], true);
		FileWriter myFileWriterCacheMemory=new FileWriter("cacheMemory"+args[4], true);
		Long numberCacheAccess=0L;
		for ( MyThreadTest thread : tabThreads )
		{
			numberCacheAccess+=thread.getTab().get(thread.getTab().size()-1).getNbInsertion();
		}
		myFileWriter.write(String.valueOf(numberCacheAccess)+"\n");
		myFileWriterCacheMemory.write(String.valueOf(nbBytesEnd-nbBytesBegin)+"\n");
		myFileWriter.close();
		myFileWriterCacheMemory.close();
	}
}